import 'package:dio/dio.dart';
import '../../core/constants/api_constants.dart';
import '../../core/utils/rate_limiter.dart';
import '../models/anime_model.dart';

/// 动漫远程数据源
/// 使用Jikan API (免费的MyAnimeList API)
class AnimeRemoteDataSource {
  final Dio _dio;
  final RateLimiter _rateLimiter;

  AnimeRemoteDataSource({
    required Dio dio,
    required RateLimiter rateLimiter,
  }) : _dio = dio, _rateLimiter = rateLimiter;

  /// 获取热门动漫列表
  Future<List<AnimeModel>> getTopAnime({
    int page = 1,
    String type = 'anime',
    String filter = 'bypopularity',
    int limit = 25,
  }) async {
    await _rateLimiter.waitForNextRequest();
    
    try {
      final response = await _dio.get(
        '/top/anime',
        queryParameters: {
          'page': page,
          'filter': filter,
          'limit': limit, // 使用动态limit参数
        },
      );

      if (response.statusCode == 200) {
        final responseData = response.data;
        if (responseData is Map<String, dynamic> && responseData['data'] is List) {
          final data = responseData['data'] as List;
          final results = <AnimeModel>[];
          for (var item in data) {
            try {
              if (item is Map<String, dynamic> && item.isNotEmpty) {
                final anime = AnimeModel.fromJson(item);
                results.add(anime);
              }
            } catch (e) {
              print('跳过有问题的热门动漫数据: $e');
              continue;
            }
          }
          return results;
        } else {
          throw Exception('API返回的数据格式不正确');
        }
      } else {
        throw Exception('获取热门动漫失败: HTTP ${response.statusCode}');
      }
    } on DioException catch (e) {
      if (e.response?.statusCode == 429) {
        // 触发频率限制，等待更长时间后重试
        await Future.delayed(const Duration(seconds: 10));
        throw Exception('请求过于频繁，请稍后再试');
      }
      throw Exception('网络请求失败: ${e.message ?? "未知网络错误"}');
    } catch (e) {
      throw Exception('获取热门动漫过程中发生错误: $e');
    }
  }

  /// 搜索动漫
  Future<List<AnimeModel>> searchAnime({
    required String query,
    int page = 1,
    String? type,
    String? status,
    String? genre,
  }) async {
    await _rateLimiter.waitForNextRequest();
    
    try {
      // 确保查询字符串正确编码
      final encodedQuery = Uri.encodeComponent(query);
      
      final queryParams = {
        'q': encodedQuery,
        'page': page,
        'limit': 20,
        // 移除固定的type参数，因为Jikan API v4不接受'anime'作为type值
      };
      
      // 添加可选参数（只有在明确指定且有效时才添加）
      if (status != null) queryParams['status'] = status;
      if (genre != null) queryParams['genres'] = genre;
      // 只有在type参数有效时才添加（排除'anime'这个无效值）
      if (type != null && type != 'anime') queryParams['type'] = type;

      final response = await _dio.get(
        '/anime',
        queryParameters: queryParams,
      );

      if (response.statusCode == 200) {
        final responseData = response.data;
        if (responseData is Map<String, dynamic> && responseData['data'] is List) {
          final data = responseData['data'] as List;
          // 过滤掉可能有问题的数据
          final results = <AnimeModel>[];
          for (var item in data) {
            try {
              if (item is Map<String, dynamic>) {
                final anime = AnimeModel.fromJson(item);
                results.add(anime);
              }
            } catch (e) {
              // 跳过有问题的项目，继续处理其他项目
              print('跳过有问题的动漫数据: $e');
              continue;
            }
          }
          return results;
        } else {
          throw Exception('API返回的数据格式不正确');
        }
      } else {
        throw Exception('搜索失败: HTTP ${response.statusCode}');
      }
    } on DioException catch (e) {
      if (e.response?.statusCode == 429) {
        await Future.delayed(const Duration(seconds: 10));
        throw Exception('请求过于频繁，请稍后再试');
      } else if (e.response?.statusCode == 400) {
        throw Exception('搜索关键词无效，请尝试其他关键词');
      } else if (e.response?.statusCode == 404) {
        throw Exception('未找到相关结果');
      }
      throw Exception('搜索失败: ${e.message ?? "未知网络错误"}');
    } catch (e) {
      throw Exception('搜索过程中发生错误: $e');
    }
  }

  /// 获取动漫详情
  Future<AnimeModel> getAnimeDetails(int animeId) async {
    await _rateLimiter.waitForNextRequest();
    
    try {
      final response = await _dio.get('/anime/$animeId');

      if (response.statusCode == 200) {
        final responseData = response.data;
        if (responseData is Map<String, dynamic> && responseData['data'] is Map<String, dynamic>) {
          try {
            return AnimeModel.fromJson(responseData['data']);
          } catch (e) {
            throw Exception('动漫详情数据解析失败: $e');
          }
        } else {
          throw Exception('API返回的数据格式不正确');
        }
      } else {
        throw Exception('获取动漫详情失败: HTTP ${response.statusCode}');
      }
    } on DioException catch (e) {
      if (e.response?.statusCode == 429) {
        await Future.delayed(const Duration(seconds: 10));
        throw Exception('请求过于频繁，请稍后再试');
      } else if (e.response?.statusCode == 404) {
        throw Exception('动漫不存在');
      }
      throw Exception('获取详情失败: ${e.message ?? "未知网络错误"}');
    } catch (e) {
      throw Exception('获取动漫详情过程中发生错误: $e');
    }
  }

  /// 获取动漫推荐
  Future<List<AnimeModel>> getAnimeRecommendations(int animeId) async {
    await _rateLimiter.waitForNextRequest();
    
    try {
      final response = await _dio.get('/anime/$animeId/recommendations');

      if (response.statusCode == 200) {
        final responseData = response.data;
        if (responseData is Map<String, dynamic> && responseData['data'] is List) {
          final data = responseData['data'] as List;
          final results = <AnimeModel>[];
          for (var item in data) {
            try {
              if (item is Map<String, dynamic> && item['entry'] is Map<String, dynamic>) {
                final entryData = item['entry'] as Map<String, dynamic>;
                if (entryData.isNotEmpty) {
                  final anime = AnimeModel.fromJson(entryData);
                  results.add(anime);
                }
              }
            } catch (e) {
              print('跳过有问题的推荐动漫数据: $e');
              continue;
            }
          }
          return results;
        } else {
          throw Exception('API返回的数据格式不正确');
        }
      } else {
        throw Exception('获取推荐失败: HTTP ${response.statusCode}');
      }
    } on DioException catch (e) {
      if (e.response?.statusCode == 429) {
        await Future.delayed(const Duration(seconds: 10));
        throw Exception('请求过于频繁，请稍后再试');
      }
      throw Exception('获取推荐失败: ${e.message ?? "未知网络错误"}');
    } catch (e) {
      throw Exception('获取推荐过程中发生错误: $e');
    }
  }

  /// 获取当季动漫
  Future<List<AnimeModel>> getSeasonalAnime({
    int? year,
    String season = 'now',
    int page = 1,
  }) async {
    await _rateLimiter.waitForNextRequest();
    
    try {
      final url = year != null ? '/seasons/$year/$season' : '/seasons/now';
      
      final response = await _dio.get(
        url,
        queryParameters: {
          'page': page,
          'limit': 20,
        },
      );

      if (response.statusCode == 200) {
        final responseData = response.data;
        if (responseData is Map<String, dynamic> && responseData['data'] is List) {
          final data = responseData['data'] as List;
          final results = <AnimeModel>[];
          for (var item in data) {
            try {
              if (item is Map<String, dynamic>) {
                final anime = AnimeModel.fromJson(item);
                results.add(anime);
              }
            } catch (e) {
              print('跳过有问题的当季动漫数据: $e');
              continue;
            }
          }
          return results;
        } else {
          throw Exception('API返回的数据格式不正确');
        }
      } else {
        throw Exception('获取当季动漫失败: HTTP ${response.statusCode}');
      }
    } on DioException catch (e) {
      if (e.response?.statusCode == 429) {
        await Future.delayed(const Duration(seconds: 10));
        throw Exception('请求过于频繁，请稍后再试');
      }
      throw Exception('获取当季动漫失败: ${e.message ?? "未知网络错误"}');
    } catch (e) {
      throw Exception('获取当季动漫过程中发生错误: $e');
    }
  }

  /// 获取即将上线的动漫 (用于轮播图)
  Future<List<AnimeModel>> getUpcomingAnime({
    int page = 1,
    int limit = 5,
  }) async {
    await _rateLimiter.waitForNextRequest();
    
    try {
      final response = await _dio.get(
        '/seasons/upcoming',
        queryParameters: {
          'page': page,
          'limit': limit,
        },
      );

      if (response.statusCode == 200) {
        final responseData = response.data;
        if (responseData is Map<String, dynamic> && responseData['data'] is List) {
          final data = responseData['data'] as List;
          final results = <AnimeModel>[];
          for (var item in data) {
            try {
              if (item is Map<String, dynamic> && item.isNotEmpty) {
                final anime = AnimeModel.fromJson(item);
                results.add(anime);
              }
            } catch (e) {
              print('跳过有问题的即将上线动漫数据: $e');
              continue;
            }
          }
          return results;
        } else {
          throw Exception('API返回的数据格式不正确');
        }
      } else {
        throw Exception('获取即将上线动漫失败: HTTP ${response.statusCode}');
      }
    } on DioException catch (e) {
      if (e.response?.statusCode == 429) {
        await Future.delayed(const Duration(seconds: 10));
        throw Exception('请求过于频繁，请稍后再试');
      }
      throw Exception('获取即将上线动漫失败: ${e.message ?? "未知网络错误"}');
    } catch (e) {
      throw Exception('获取即将上线动漫过程中发生错误: $e');
    }
  }

  /// 获取最新最火的动漫 (用于推荐)
  Future<List<AnimeModel>> getTrendingAnime({
    int page = 1,
    int limit = 20,
  }) async {
    await _rateLimiter.waitForNextRequest();
    
    try {
      final response = await _dio.get(
        '/top/anime',
        queryParameters: {
          'page': page,
          'limit': 25, // 确保获取前25名
        },
      );

      if (response.statusCode == 200) {
        final responseData = response.data;
        if (responseData is Map<String, dynamic> && responseData['data'] is List) {
          final data = responseData['data'] as List;
          final results = <AnimeModel>[];
          for (var item in data) {
            try {
              if (item is Map<String, dynamic> && item.isNotEmpty) {
                final anime = AnimeModel.fromJson(item);
                results.add(anime);
              }
            } catch (e) {
              print('跳过有问题的热门动漫数据: $e');
              continue;
            }
          }
          // 只返回排名前25的动漫
          return results.take(25).toList();
        } else {
          throw Exception('API返回的数据格式不正确');
        }
      } else {
        throw Exception('获取热门动漫失败: HTTP ${response.statusCode}');
      }
    } on DioException catch (e) {
      if (e.response?.statusCode == 429) {
        await Future.delayed(const Duration(seconds: 10));
        throw Exception('请求过于频繁，请稍后再试');
      }
      throw Exception('获取热门动漫失败: ${e.message ?? "未知网络错误"}');
    } catch (e) {
      throw Exception('获取热门动漫过程中发生错误: $e');
    }
  }

  /// 根据分类获取动漫
  Future<List<AnimeModel>> getAnimeByGenre({
    required int genreId,
    int page = 1,
    int limit = 20,
  }) async {
    await _rateLimiter.waitForNextRequest();
    
    try {
      final response = await _dio.get(
        '/anime',
        queryParameters: {
          'genres': genreId.toString(),
          'page': page,
          'limit': limit,
          'order_by': 'score',
          'sort': 'desc',
        },
      );

      if (response.statusCode == 200) {
        final responseData = response.data;
        if (responseData is Map<String, dynamic> && responseData['data'] is List) {
          final data = responseData['data'] as List;
          final results = <AnimeModel>[];
          for (var item in data) {
            try {
              if (item is Map<String, dynamic>) {
                final anime = AnimeModel.fromJson(item);
                results.add(anime);
              }
            } catch (e) {
              print('跳过有问题的分类动漫数据: $e');
              continue;
            }
          }
          return results;
        } else {
          throw Exception('API返回的数据格式不正确');
        }
      } else {
        throw Exception('获取分类动漫失败: HTTP ${response.statusCode}');
      }
    } on DioException catch (e) {
      if (e.response?.statusCode == 429) {
        await Future.delayed(const Duration(seconds: 10));
        throw Exception('请求过于频繁，请稍后再试');
      }
      throw Exception('获取分类动漫失败: ${e.message ?? "未知网络错误"}');
    } catch (e) {
      throw Exception('获取分类动漫过程中发生错误: $e');
    }
  }

  /// 根据状态获取动漫
  Future<List<AnimeModel>> getAnimeByStatus({
    required String status,
    int page = 1,
    int limit = 20,
  }) async {
    await _rateLimiter.waitForNextRequest();
    
    try {
      final response = await _dio.get(
        '/anime',
        queryParameters: {
          'status': status,
          'page': page,
          'limit': limit,
          'order_by': 'score',
          'sort': 'desc',
        },
      );

      if (response.statusCode == 200) {
        final responseData = response.data;
        if (responseData is Map<String, dynamic> && responseData['data'] is List) {
          final data = responseData['data'] as List;
          final results = <AnimeModel>[];
          for (var item in data) {
            try {
              if (item is Map<String, dynamic>) {
                final anime = AnimeModel.fromJson(item);
                results.add(anime);
              }
            } catch (e) {
              print('跳过有问题的状态动漫数据: $e');
              continue;
            }
          }
          return results;
        } else {
          throw Exception('API返回的数据格式不正确');
        }
      } else {
        throw Exception('获取状态动漫失败: HTTP ${response.statusCode}');
      }
    } on DioException catch (e) {
      if (e.response?.statusCode == 429) {
        await Future.delayed(const Duration(seconds: 10));
        throw Exception('请求过于频繁，请稍后再试');
      }
      throw Exception('获取状态动漫失败: ${e.message ?? "未知网络错误"}');
    } catch (e) {
      throw Exception('获取状态动漫过程中发生错误: $e');
    }
  }

  /// 根据类型获取动漫
  Future<List<AnimeModel>> getAnimeByType({
    required String type,
    int page = 1,
    int limit = 20,
  }) async {
    await _rateLimiter.waitForNextRequest();
    
    try {
      final response = await _dio.get(
        '/anime',
        queryParameters: {
          'type': type,
          'page': page,
          'limit': limit,
          'order_by': 'score',
          'sort': 'desc',
        },
      );

      if (response.statusCode == 200) {
        final responseData = response.data;
        if (responseData is Map<String, dynamic> && responseData['data'] is List) {
          final data = responseData['data'] as List;
          final results = <AnimeModel>[];
          for (var item in data) {
            try {
              if (item is Map<String, dynamic>) {
                final anime = AnimeModel.fromJson(item);
                results.add(anime);
              }
            } catch (e) {
              print('跳过有问题的类型动漫数据: $e');
              continue;
            }
          }
          return results;
        } else {
          throw Exception('API返回的数据格式不正确');
        }
      } else {
        throw Exception('获取类型动漫失败: HTTP ${response.statusCode}');
      }
    } on DioException catch (e) {
      if (e.response?.statusCode == 429) {
        await Future.delayed(const Duration(seconds: 10));
        throw Exception('请求过于频繁，请稍后再试');
      }
      throw Exception('获取类型动漫失败: ${e.message ?? "未知网络错误"}');
    } catch (e) {
      throw Exception('获取类型动漫过程中发生错误: $e');
    }
  }

  /// 获取最新集数动漫
  Future<List<AnimeModel>> getRecentEpisodes({
    int limit = 15,
  }) async {
    await _rateLimiter.waitForNextRequest();
    
    try {
      final response = await _dio.get(
        '/anime',
        queryParameters: {
          'status': 'airing',
          'limit': limit,
          'order_by': 'start_date',
          'sort': 'desc',
        },
      );

      if (response.statusCode == 200) {
        final responseData = response.data;
        if (responseData is Map<String, dynamic> && responseData['data'] is List) {
          final data = responseData['data'] as List;
          final results = <AnimeModel>[];
          for (var item in data) {
            try {
              if (item is Map<String, dynamic>) {
                final anime = AnimeModel.fromJson(item);
                results.add(anime);
              }
            } catch (e) {
              print('跳过有问题的最新集数动漫数据: $e');
              continue;
            }
          }
          return results;
        } else {
          throw Exception('API返回的数据格式不正确');
        }
      } else {
        throw Exception('获取最新集数动漫失败: HTTP ${response.statusCode}');
      }
    } on DioException catch (e) {
      if (e.response?.statusCode == 429) {
        await Future.delayed(const Duration(seconds: 10));
        throw Exception('请求过于频繁，请稍后再试');
      }
      throw Exception('获取最新集数动漫失败: ${e.message ?? "未知网络错误"}');
    } catch (e) {
      throw Exception('获取最新集数动漫过程中发生错误: $e');
    }
  }
} 